﻿package org.openChart.sprite.elements
{
	import flash.display.Sprite;
	import flash.geom.Point;
	import org.openChart.display.DisplayElement;
	import flash.events.MouseEvent;
	import org.openChart.sprite.MouseEventSprite;
	import org.openChart.sprite.CommandHandler;
	import org.openChart.sprite.ToolTipSprite;
	import org.openChart.sprite.Color;
	import org.openChart.sprite.Command;
	
	/**
	 * The base class of all chart element sprite. Each chart element has a value.
	 * 
	 * @author Chongyuan
	 */
	public class ElementSprite extends MouseEventSprite implements BaseElementInterface
	{
		// The sprite to show the value of chart element.
		protected var valueField:Sprite;
		protected var color:uint;
		/**
		 * The constructor of chart element sprite.
		 * 
		 * @param	displayObject The display model of chart element.
		 * @param	commandHandler The command handler of chart element.
		 */
		public function ElementSprite(displayObject:DisplayElement, commandHandler:CommandHandler) 
		{
			
			//this.alpha = displayObject.alpha;
			//trace(displayObject.alpha);
			this.alpha = displayObject.alpha;
			color = displayObject.color;
			super(displayObject, commandHandler);
		}
		
		/**
		 * The function is used to initialize the sprite to show the value.
		 */
		public function initValue():void
		{
			
		}
		
		public override function repaint():void
		{
			this.paint();
		}
		
		public override function mouseOver( event:MouseEvent ):void
		{
			var displayElement:DisplayElement = displayObject as DisplayElement;
			this.alpha = displayElement.selectedAlpha;
			this.color = displayElement.selectedColor;
			repaint();
			
			var position:Point = new Point(event.stageX, event.stageY);
			var object:Object = new Object();
			object.value = displayElement.value;
			commandHandler.processMouseCommand(Command.TOOLTIP_SHOW, this, position, object);
			
			super.mouseOver(event);
		}
		
		public override function mouseOut( event:MouseEvent ):void
		{
			var displayElement:DisplayElement = displayObject as DisplayElement;
			this.alpha = displayElement.alpha;
			this.color = displayElement.color;
			repaint();
			
			commandHandler.processMouseCommand(Command.TOOLTIP_HIDE, this, null, null);
			
			super.mouseOut(event);
		}
		
		public override function mouseMove( event:MouseEvent ):void
		{
			var displayElement:DisplayElement = displayObject as DisplayElement;
			var position:Point = new Point(event.stageX, event.stageY);
			var object:Object = new Object();
			object.value = displayElement.value;
			commandHandler.processMouseCommand(Command.TOOLTIP_SHOW, this, position, object);
		}
		
		protected function drawSector2d(x_:Number, y_:Number, radius_x:Number, radius_y:Number, angle_1:Number, angle_2:Number, thickness:Number = 0, color:uint = 0, alpha:Number = 1):void
		{
			graphics.lineStyle(thickness, color, alpha);
			graphics.moveTo(x_, y_);
			drawEllipseArc(x_, y_, radius_x, radius_y, angle_1, angle_2, 0, thickness, color);
			graphics.lineTo(x_, y_);
		}
		
		protected function fillSector2d(x_:Number, y_:Number, radius_x:Number, radius_y:Number, angle_1:Number, angle_2:Number, fill_color:uint, fill_alpha:Number = 1, thickness:Number = 0, color:uint = 0, alpha:Number = 1):void
		{
			graphics.beginFill(fill_color, fill_alpha);
			drawSector2d(x_, y_, radius_x, radius_y, angle_1, angle_2, thickness, color, alpha);
			graphics.endFill();
		}
		
		protected function fillSector3d(x:Number, y:Number, radius_x:Number, radius_y:Number, angle_1:Number, angle_2:Number, view_angle:Number, thickness_:Number, fill_color:uint, fill_alpha:Number = 1, thickness:Number = 0, color:uint = 0, alpha:Number = 1):void
		{
			graphics.lineStyle(thickness, color, alpha);
			var PI:Number = Math.PI;
			//
			var colorObject:Color = new Color(fill_color)
			
			while (angle_1 > 360)
			{
				angle_1 -= 360;
			}
			while (angle_2 > 360)
			{
				angle_2 -= 360;
			}
			while (angle_1 > angle_2)
			{
				angle_2 = angle_2 + 360;
			}
			
			var beginAngle:Number = angle_1 / 180 * PI;
			var endAngle:Number = angle_2 / 180 * PI;
			var viewAngle:Number = view_angle / 180 * PI;
			
			var width:Number = radius_x;
			var height:Number = radius_y * Math.cos(viewAngle);
			thickness_ = thickness_ * Math.sin(viewAngle);
			//trace(thickness_);
			
			if (beginAngle < PI / 2 || beginAngle > 3*PI/2)
			{
				
				graphics.beginFill(colorObject.getLighter(0.2), fill_alpha);
				graphics.moveTo(x, y);
				graphics.lineTo(Math.cos(beginAngle) * width + x, y - Math.sin(beginAngle) * height);
				graphics.lineTo(Math.cos(beginAngle) * width + x, y - Math.sin(beginAngle) * height + thickness_);
				graphics.lineTo(x, y + thickness_);
				graphics.lineTo(x, y);
				graphics.endFill();
			}
			
			graphics.beginFill(colorObject.getColor());
			graphics.moveTo(x, y);
			graphics.lineStyle(0);
			graphics.lineTo(Math.cos(beginAngle) * width + x, y - Math.sin(beginAngle) * height);
			drawEllipseArc(x, y, width, height, angle_1, angle_2, 0);
			graphics.lineTo(Math.cos(endAngle) * width + x, y - Math.sin(endAngle) * height);
			graphics.lineTo(x, y);
			graphics.endFill();
			
			if (beginAngle > PI || endAngle > PI)
			{
				
				graphics.beginFill(colorObject.getLighter(0.1));
				var maxBeginAngle:Number = Math.max(PI, beginAngle);
				var minEndAngle:Number = Math.min(2 * PI, endAngle);
				graphics.lineStyle(0);
				graphics.moveTo(Math.cos(maxBeginAngle) * width + x, y - Math.sin(maxBeginAngle) * height);
				drawEllipseArc(x, y, width, height, maxBeginAngle / PI * 180, minEndAngle / PI * 180, 0);
				graphics.lineTo(Math.cos(minEndAngle) * width + x, y - Math.sin(minEndAngle) * height);
				graphics.lineTo(Math.cos(minEndAngle) * width + x, y - Math.sin(minEndAngle) * height + thickness_);
				drawEllipseArc(x, y + thickness_, width, height, maxBeginAngle / PI * 180, minEndAngle / PI * 180, 1);
				graphics.lineTo(Math.cos(maxBeginAngle) * width + x, y - Math.sin(maxBeginAngle) * height + thickness_);
				graphics.lineTo(Math.cos(maxBeginAngle) * width + x, y - Math.sin(maxBeginAngle) * height);
				graphics.endFill();
			}
			
			if (endAngle > PI / 2 && endAngle < 3*PI / 2)
			{
				
				//graphics.lineStyle(0);
				graphics.beginFill(colorObject.getLighter(0.2));
				graphics.moveTo(x, y);
				graphics.lineTo(Math.cos(endAngle) * width + x, y - Math.sin(endAngle) * height);
				graphics.lineTo(Math.cos(endAngle) * width + x, y - Math.sin(endAngle) * height + thickness_);
				graphics.lineTo(x, y + thickness_);
				graphics.lineTo(x, y);
				graphics.endFill();
			}
		}
	}
	
}